/* -----------------------------------------------------------------------------
// Offset + Dark Current -- Batch script
//           Version 23.08.2012
//
// Intended to be paired with a sequence of scripts:
//   -Offset + Dark CurrentFileNumber
//   -Sun (Kurusz) or Lamp Calibration
//   -Possibly gas concentration fits.
//   
//   ^^^These scripts are then intended to be run individually, or
//       sequentially using a DOS batch file
//       
//       If run sequentially, the date + spectrometer must be changed in *EACH* script
// 
//       What this script needs:
//           Offset File   
//           DarkCurrent File    (SHOULD ALREADY BE OFFSET CORRECTED!!)
//           Measurement Spectra (under subfolder "spectra_raw")
// 
// 
// -------------------------------------------------------------------------------          
// 
// by Eric Gentry
// questions: Tilman.Hueneke@iup.uni-heidelberg.de
//            egentry@mit.edu
//            
// ------------------------------------------------------------------------------*/
    
    import System
    import System.IO
    import System.Threading
    import DoasCore
    import DoasCore.Spectra
    import DoasCore.IO
    import DoasCore.Device
    import DoasCore.Script
    import DoasCore.HMI
    import DoasCore.Math


// ========== UPDATE DATA IN THESE FILES! ==========
   
    //Below files must be in same folder as this script.
   var FolderLocationsFile   = "INFO_FolderLocations.txt"             
   var RunInputFile          = "INFO_DataProcessDirectory.txt"

   var bSingleRun            = false     //Only do one 1 spectrum? For debugging      
         
  // ========== Read-in User-define settings ==========     
  
  var FolderLocations        = FolderLocationsParse(FolderLocationsFile)     
  
  var BasePath               = FolderLocations.BasePath  
        
//**********************Main Function (wrapper function)***************************************//  

   function main()
   {
    var RunInfoArray_Temp = RunParse(RunInputFile)
    var RunInfoArray      = FilterRunArray(RunInfoArray_Temp)
              
    for(var index in RunInfoArray)
       {  
          Process(RunInfoArray[index])
          
          if(Script.StopAllScripts)
            {break}
       }
    
    Console.WriteLine("Offset + Dark Current Script stopped")
  
   }
//*****************************************************************************************//  

  
   // ===================================================
   //                    Processing Function
   // ===================================================
  
    function Process(ProcessingInfoObject)
{
    
     var Date            = ProcessingInfoObject.Date
     var Spectrometer    = ProcessingInfoObject.Spectrometer

/*      //Examples: DO NOT UNCOMMENT
//         ProcessingInfoObject.Date          = "2012_06_16";  //MAKE SURE TO CHANGE REF SPEC!!!
//         ProcessingInfoObject.Spectrometer  = "VIS4";        //Must be capital letters
*/

    var OffsetFile      = BasePath + Date + "_" + FolderLocations.CalibrationFiles + "\\" + Spectrometer + "\\CalibFiles\\" + Spectrometer + "_Offset.sp2";      
    var DarkCurrentFile = BasePath + Date + "_" + FolderLocations.CalibrationFiles + "\\" + Spectrometer + "\\CalibFiles\\" + Spectrometer + "_DarkCurrent.sp2";          
       //REMEMBER: you need to *manually* offset-correct the DarkCurrent file
 
    
      // ============ Checking if paths exist
    var RawSpecPath = BasePath + Date + "_" + FolderLocations.FlightFiles + "\\" + Spectrometer +  "\\spectra_raw\\";
    var di = new DirectoryInfo(RawSpecPath)
    if(!di.Exists)
      {Console.WriteLine("Run path does not exist!!!")
       Console.WriteLine(RawSpecPath)
      return;
      }
                            
    var CorrectedSpecPath = BasePath + Date + "_" + FolderLocations.FlightFiles + "\\" + Spectrometer + "\\spectra_corrected_Offset_DC\\";
    di = new DirectoryInfo(CorrectedSpecPath)
    if(!di.Exists)
      {
      di.Create()
      } 
       
    
   // ========= Spectrum Objects =========
  
   var SpectraPrefix              = "M";
   var SpectraSuffix              = ".std";
   var NumberOfDigitsInName       = 6      //Eg. M123456.std has NumberOfDigitsInName == 6 
                                
   var MeasFile : AutoFileName    = new AutoFileName()
       MeasFile.BasePath          = RawSpecPath
       MeasFile.Prefix            = SpectraPrefix
       MeasFile.Suffix            = SpectraSuffix
       MeasFile.NumberOfDigits    = NumberOfDigitsInName 
       MeasFile.Mode              = "Manual"; //Enables you to skip the "M000000" folder in the filepath
       MeasFile.FindFirstIndex()     
       
   var SaveFile : AutoFileName    = new AutoFileName()
       SaveFile.BasePath          = CorrectedSpecPath
       SaveFile.Prefix            = SpectraPrefix
       SaveFile.Suffix            = SpectraSuffix
       SaveFile.NumberOfDigits    = NumberOfDigitsInName
       SaveFile.Mode              = "Manual";
       SaveFile.CurrentFileNumber = MeasFile.CurrentFileNumber    
    
     
  
   var OffsetSpec       :ISpectrum = Specbar.GetSpectrum("Offset") 
   var DarkCurrentSpec  :ISpectrum = Specbar.GetSpectrum("DarkCurrent")
   var MeasSpec         :ISpectrum = Specbar.GetSpectrum("Measurement Spectrum")
    
        OffsetSpec.Open(OffsetFile)
   DarkCurrentSpec.Open(DarkCurrentFile)
         
     
     while(!Script.StopAllScripts && MeasFile.Open(MeasSpec))
     {
      Console.WriteLine(MeasSpec.FileName.substring(MeasSpec.FileName.lastIndexOf("\\") +1))
      SpecMath.CorrectOffset(MeasSpec, OffsetSpec)
      SpecMath.CorrectDarkCurrent(MeasSpec, DarkCurrentSpec)
      
      //Temporarily change spectrum ObjectKey
      //This way [later] we can open multiple spectrum in DOASIS
      MeasSpec.ObjectKey = MeasSpec.FileName.substring(MeasSpec.FileName.lastIndexOf("\\") +1)
      SaveFile.Save(MeasSpec)
      MeasSpec.ObjectKey = "Measurement Spectrum";
      
      if(bSingleRun == true)
        {break}
      
      }
   
    }

//*****************************************************************************************//  
    
    
function RunParse(InputFile)
//  Uses an ActiveX object to give JavaScript the ability to read a text file
//  First line is discarded (header information)
//  Further lines are space-delimited.
//  Returns an array of Objects
    {
     var ReadFileSystem = new ActiveXObject("Scripting.FileSystemObject")
     var infile         = ReadFileSystem.GetFile(InputFile)
     var infileStream   = infile.OpenAsTextStream(1, 0)

     var TemporaryArray   = new Array()
     var OutputArray      = new Array()
     var TempLine         = ""
   
     for(var count = 0; !infileStream.AtEndOfStream; count++)
     {
        TempLine = infileStream.ReadLine()
        
        if(count == 0)
           continue
        
        if(TempLine == "")
           continue
           
        else
          TemporaryArray.push(TempLine.split(" "))
     } 
     
     infileStream.Close()
     
     
     for(var index in TemporaryArray)
        {
          var RunInfoObject = {"Date"         : TemporaryArray[index][0],
                               "Spectrometer" : TemporaryArray[index][1].toUpperCase(),
                               //"CalibStyle"   : SolarOrLampCalib(TemporaryArray[index][2]),
                               "RefSpecName"  : TemporaryArray[index][3],
                               "TraceGasName" : TemporaryArray[index][4].toUpperCase()}
                               
          OutputArray.push(RunInfoObject)     
        }
 
        //Getting an "Object Expected" Error? Your input file doesn't have enough information!
     
     return OutputArray 
    } 
    
//*****************************************************************************************//      
     
function FilterRunArray(InputArray)
     //===Check for repeated sets of dates + spectrometer pairs
{ 
     var FilteredList = new Object()
     var OutputArray  = new Array()
     
     for(var index in InputArray)   //Filter Repeat day + spectrometer pairs
     {    
        var TempString  = InputArray[index].Date + " " + InputArray[index].Spectrometer;
            FilteredList[TempString] = true       
     }
     
     for(var ValidString in FilteredList)
     {
         var TemporaryArray = ValidString.split(" ")  
             
         var RunInfoObject = {"Date"         : TemporaryArray[0],
                              "Spectrometer" : TemporaryArray[1]}
         
         OutputArray.push(RunInfoObject) 
     }

     return OutputArray
}

//*****************************************************************************************//      

 function FolderLocationsParse(InputFile)
//  Uses an ActiveX object to give JavaScript the ability to read a text file
//  First line is discarded (header information)
//  Further lines are space-delimited.
//  Returns an array of Objects
    {
     var ReadFileSystem   = new ActiveXObject("Scripting.FileSystemObject")
     var infile           = ReadFileSystem.GetFile(InputFile)
     var infileStream     = infile.OpenAsTextStream(1, 0)

     var TemporaryArray   = new Array()
     var OutputObject     = new Object()
     var TempLine         = ""
   
     for(var count = 0; !infileStream.AtEndOfStream; count++)
     {  
        TempLine = infileStream.ReadLine();
           
        if(count == 0)
          continue
          
        if(TempLine == "")     //skip empty lines in textfile
          continue
            
        else
          TemporaryArray.push(TempLine.split("\"")[1])   //Use " as a delimiter
     } 
     
     infileStream.Close()    
     
     var BasePath                   =  TemporaryArray[0]
     var FitScenarios_CrossSections =  TemporaryArray[1]
     
     //Add at "\" to the end of the folder names, if it is missing
     if(BasePath[BasePath.length-1] != "\\")     
        BasePath = BasePath + "\\"
     
     if(FitScenarios_CrossSections[FitScenarios_CrossSections.length -1] != "//")
        FitScenarios_CrossSections = FitScenarios_CrossSections + "\\"
     
     //construct output
     OutputObject  = {"BasePath"                   : BasePath,
                      "FitScenarios_CrossSections" : FitScenarios_CrossSections,
                      "CalibrationFiles"           : TemporaryArray[2],
                      "FlightFiles"                : TemporaryArray[3]
                      }  
        
        //Getting an "Object Expected" Error? Your input file doesn't have enough information! (or empty lines)
     
     return OutputObject 
} 
    
//*****************************************************************************************// 

    
    main();
